﻿using LeRenard.Libraries.PlatformInspection.InfoNodes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;

namespace LeRenard.Libraries.PlatformInspection.Inspectors.Environment
{
    class PeripheralsEnvironmentInspectorModule : InspectorModule<EnvironmentInspector>
    {
        /// <summary>
        /// Constructions
        /// </summary>
        public PeripheralsEnvironmentInspectorModule() 
            : base("Peripherals") 
        { 
        }

        /// <summary>
        /// Gets the information this module gathers.
        /// </summary>        
        protected override IEnumerable<InfoNode> GetInformationImpl()
        {
            var infoNodes = new List<InfoNode>();

            var usbNode = new InfoNode(
                name: "USB Devices",
                displayStrategy: InfoNodeEmptyValueDisplayStrategy.TreatAsTitleInfoNode
            );
            infoNodes.Add(usbNode);
            foreach (var usb in GetUSBDevices())
            {
                usbNode.AddInfoNode(
                    name: usb.Name + " - v." + usb.Version + " (" + usb.SystemName + ")",
                    value: usb.Description + " (" + usb.DeviceID + " // " + usb.PnpDeviceID + ")",
                    displayStrategy: InfoNodeEmptyValueDisplayStrategy.TreatAsNormalInfoNode
                );
            }

            return infoNodes.OrderBy(inf => inf.Name);
        }

        #region USB
        /// TODO: add friendly "name" http://www.codeproject.com/Articles/60579/A-USB-Library-to-Detect-USB-Devices
        /// TODO: check http://www.activexperts.com/admin/scripts/wmi/vbscript/0316/ for WMI Querying
        private List<USBDeviceInfo> GetUSBDevices()
        {
            List<USBDeviceInfo> devices = new List<USBDeviceInfo>();

            ManagementObjectCollection collection;
            using (var searcher = new ManagementObjectSearcher(@"Select * From Win32_USBHub"))
                collection = searcher.Get();

            foreach (var device in collection)
            {
                devices.Add(new USBDeviceInfo(
                (string)device.GetPropertyValue("DeviceID"),
                (string)device.GetPropertyValue("PNPDeviceID"),
                (string)device.GetPropertyValue("Description"),
                (string)device.GetPropertyValue("Name"),
                (string)device.GetPropertyValue("SystemName"),
                (string)device.GetPropertyValue("USBVersion")
                ));
            }

            collection.Dispose();
            return devices;
        }
        private class USBDeviceInfo
        {
            public USBDeviceInfo(string deviceID, string pnpDeviceID, string description, string name, string systemName, string version)
            {
                this.DeviceID = deviceID;
                this.PnpDeviceID = pnpDeviceID;
                this.Description = description;
                this.Name = name;
                this.SystemName = systemName;
                this.Version = version;
            }
            public string DeviceID { get; private set; }
            public string PnpDeviceID { get; private set; }
            public string Description { get; private set; }
            public string Name { get; private set; }
            public string SystemName { get; private set; }
            public string Version { get; private set; }
        }
        #endregion
    }
}
